home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / PROG_TOO / C013.ZIP / DES.C < prev    next >
Text File  |  1990-01-19  |  21KB  |  604 lines

  1. /********************************************************************
  2.  * C Users Group (U.K) C Source Code Library File CUGLIB.013        *
  3.  * Inquiries to: M. Houston, 36 Whetstone Clo. Farquhar Rd.         *
  4.  * Edgbaston, Birmingham B15 2QN ENGLAND                *
  5.  ********************************************************************
  6.  * File name: des.c
  7.  * Program name:des 
  8.  * Source of file: Ron Wellstead
  9.  * Purpose: duplicate the NBS Data Encryption Standard in software.
  10.  * Changes: <who what when & why major changes have been made>      
  11.  ********************************************************************/
  12.  
  13.  /* des: duplicate the NBS Data Encryption Standard in software.
  14.   * usage: des <file>
  15.   * prompts for the password
  16.   * If the filename ends in ".n" it will be decrypted with the key;
  17.   * otherwise it will be encrypted.
  18.   *
  19.   * Permutation algorithm:
  20.   *    The permutation is defined by its effect on each of the 16 nibbles
  21.   *    of the 64-bit input.  For each nibble we give an 8-byte bit array
  22.   *    that has the bits in the input nibble distributed correctly.  The
  23.   *    complete permutation involves ORing the 16 sets of 8 bytes designated
  24.   *    by the 16 input nibbles.  Uses 16*16*8 = 2K bytes of storage for
  25.   *    each 64-bit permutation.  32-bit permutations (P) and expansion (E)
  26.   *    are done similarly, but using bytes instead of nibbles.
  27.   *    Should be able to use long ints, adding the masks, at a
  28.   *    later pass.  Tradeoff: can speed 64-bit perms up at cost of slowing 
  29.   *    down expansion or contraction operations by using 8K tables here and
  30.   *    decreasing the size of the other tables.
  31.   * The compressions are pre-computed in 12-bit chunks, combining 2 of the
  32.   *    6->4 bit compressions.
  33.   * The key schedule is also precomputed.
  34.   *
  35.   * Jim Gillogly, May 1977
  36.   * Modified 8/84 by Jim Gillogly and Lauren Weinstein to compile with
  37.   *   post-1977 C compilers and systems
  38.   *
  39.   * This program is now officially in the public domain, and is available for
  40.   * any non-profit use as long as the authorship line is retained.
  41.   */
  42.  
  43.  #include <stdio.h>
  44.  
  45.  char iperm[16][16][8],fperm[16][16][8]; /* inital and final permutations*/
  46.  char s[4][4096];            /* S1 thru S8 precomputed    */
  47.  char p32[4][256][4];            /* for permuting 32-bit f output*/
  48.  char kn[16][6];                /* key selections        */
  49.  
  50.  endes(inblock,outblock)            /* encrypt 64-bit inblock    */
  51.  char *inblock, *outblock;
  52.  {    char iters[17][8];        /* workspace for each iteration */
  53.      char swap[8];            /* place to interchange L and R */
  54.      register int i;
  55.      register char *s, *t;
  56.  
  57.      permute(inblock,iperm,iters[0]);/* apply initial permutation    */
  58.      for (i=0; i<16; i++)        /* 16 churning operations    */
  59.          iter(i,iters[i],iters[i+1]);
  60.                      /* don't re-copy to save space  */
  61.      s = swap; t = &iters[16][4];    /* interchange left        */
  62.      *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  63.      t = &iters[16][0];        /* and right            */
  64.      *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  65.      permute(swap,fperm,outblock);   /* apply final permutation    */
  66.  }
  67.  
  68.  dedes(inblock,outblock)        /* decrypt 64-bit inblock    */
  69.  char *inblock,*outblock;
  70.  {    char iters[17][8];        /* workspace for each iteration */
  71.      char swap[8];            /* place to interchange L and R */
  72.      register int i;
  73.      register char *s, *t;
  74.  
  75.      permute(inblock,iperm,iters[0]);/* apply initial permutation    */
  76.      for (i=0; i<16; i++)        /* 16 churning operations    */
  77.          iter(15-i,iters[i],iters[i+1]);
  78.                      /* reverse order from encrypting*/
  79.      s = swap; t = &iters[16][4];    /* interchange left        */
  80.      *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  81.      t = &iters[16][0];        /* and right            */
  82.      *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  83.      permute(swap,fperm,outblock);   /* apply final permutation    */
  84.  }
  85.  
  86.  permute(inblock,perm,outblock)        /* permute inblock with perm    */
  87.  char *inblock, *outblock;        /* result into outblock,64 bits */
  88.  char perm[16][16][8];            /* 2K bytes defining perm.    */
  89.  {    register int i,j;
  90.      register char *ib, *ob;        /* ptr to input or output block */
  91.      register char *p, *q;
  92.  
  93.      for (i=0, ob = outblock; i<8; i++)
  94.          *ob++ = 0;        /* clear output block        */
  95.      ib = inblock;
  96.      for (j = 0; j < 16; j += 2, ib++) /* for each input nibble    */
  97.      {    ob = outblock;
  98.          p = perm[j][(*ib >> 4) & 017];
  99.          q = perm[j + 1][*ib & 017];
  100.          for (i = 0; i < 8; i++)   /* and each output byte    */
  101.              *ob++ |= *p++ | *q++;   /* OR the masks together*/
  102.      }
  103.  }
  104.  
  105.  char ip[]                /* initial permutation P    */
  106.  = {    58, 50, 42, 34, 26, 18, 10,  2,
  107.      60, 52, 44, 36, 28, 20, 12,  4,
  108.      62, 54, 46, 38, 30, 22, 14,  6,
  109.      64, 56, 48, 40, 32, 24, 16,  8,
  110.      57, 49, 41, 33, 25, 17,  9,  1,
  111.      59, 51, 43, 35, 27, 19, 11,  3,
  112.      61, 53, 45, 37, 29, 21, 13,  5,
  113.      63, 55, 47, 39, 31, 23, 15,  7    };
  114.  
  115.  char fp[]                /* final permutation F      */
  116.  = {    40,  8, 48, 16, 56, 24, 64, 32,
  117.      39,  7, 47, 15, 55, 23, 63, 31,
  118.      38,  6, 46, 14, 54, 22, 62, 30,
  119.      37,  5, 45, 13, 53, 21, 61, 29,
  120.      36,  4, 44, 12, 52, 20, 60, 28,
  121.      35,  3, 43, 11, 51, 19, 59, 27,
  122.      34,  2, 42, 10, 50, 18, 58, 26,
  123.      33,  1, 41,  9, 49, 17, 57, 25    };
  124.  
  125.  /* expansion operation matrix   */    /* rwo: unused    */
  126.  /* char ei[] = {    32,  1,  2,  3,  4,  5,
  127.       4,  5,  6,  7,  8,  9,
  128.       8,  9, 10, 11, 12, 13,
  129.      12, 13, 14, 15, 16, 17,
  130.      16, 17, 18, 19, 20, 21,
  131.      20, 21, 22, 23, 24, 25,
  132.      24, 25, 26, 27, 28, 29,
  133.      28, 29, 30, 31, 32,  1  };    */
  134.  
  135.  char pc1[]                /* permuted choice table (key)  */
  136.  = {    57, 49, 41, 33, 25, 17,  9,
  137.       1, 58, 50, 42, 34, 26, 18,
  138.      10,  2, 59, 51, 43, 35, 27,
  139.      19, 11,  3, 60, 52, 44, 36,
  140.  
  141.      63, 55, 47, 39, 31, 23, 15,
  142.       7, 62, 54, 46, 38, 30, 22,
  143.      14,  6, 61, 53, 45, 37, 29,
  144.      21, 13,  5, 28, 20, 12,  4    };
  145.  
  146.  char totrot[]               /* number left rotations of pc1 */
  147.  = {    1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28    };
  148.  
  149.  char pc1m[56];              /* place to modify pc1 into    */
  150.  char pcr[56];               /* place to rotate pc1 into    */
  151.  
  152.  char pc2[]                /* permuted choice key (table)  */
  153.  = {    14, 17, 11, 24,  1,  5,
  154.       3, 28, 15,  6, 21, 10,
  155.      23, 19, 12,  4, 26,  8,
  156.      16,  7, 27, 20, 13,  2,
  157.      41, 52, 31, 37, 47, 55,
  158.      30, 40, 51, 45, 33, 48,
  159.      44, 49, 39, 56, 34, 53,
  160.      46, 42, 50, 36, 29, 32    };
  161.  
  162.  char si[8][64]              /* 48->32 bit compression tables*/
  163.  = {                    /* S[1]             */
  164.      14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
  165.       0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
  166.       4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
  167.      15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
  168.                      /* S[2]             */
  169.      15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
  170.       3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
  171.       0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
  172.      13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
  173.                      /* S[3]             */
  174.      10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
  175.      13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
  176.      13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
  177.       1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
  178.                      /* S[4]             */
  179.       7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
  180.      13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
  181.      10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
  182.       3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
  183.                      /* S[5]             */
  184.       2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
  185.      14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
  186.       4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
  187.      11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
  188.                      /* S[6]             */
  189.      12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
  190.      10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
  191.       9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
  192.       4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
  193.                      /* S[7]             */
  194.       4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
  195.      13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
  196.       1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
  197.       6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
  198.                      /* S[8]             */
  199.      13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
  200.       1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
  201.       7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
  202.       2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11    };
  203.  
  204.  char p32i[]                /* 32-bit permutation function  */
  205.  = {    16,  7, 20, 21,
  206.      29, 12, 28, 17,
  207.       1, 15, 23, 26,
  208.       5, 18, 31, 10,
  209.       2,  8, 24, 14,
  210.      32, 27,  3,  9,
  211.      19, 13, 30,  6,
  212.      22, 11,  4, 25    };
  213.  
  214.  desinit(key)                /* initialize all des arrays    */
  215.  char *key;
  216.  {
  217.  #ifdef DEBUG
  218.  /*deb*/ printf("Initial perm init.\n");
  219.  #endif
  220.      perminit(iperm,ip);        /* initial permutation        */
  221.  #ifdef DEBUG
  222.  /*deb*/ printf("Final perm init.\n");
  223.  #endif
  224.      perminit(fperm,fp);        /* final permutation        */
  225.  #ifdef DEBUG
  226.  /*deb*/ printf("Key sched init.\n");
  227.  #endif
  228.      kinit(key);            /* key schedule            */
  229.  #ifdef DEBUG
  230.  /*deb*/ printf("Compression init.\n");
  231.  #endif
  232.      sinit();            /* compression functions    */
  233.  
  234.  #ifdef DEBUG
  235.  /*deb*/ printf("32-bit perm init.\n");
  236.  #endif
  237.      p32init();            /* 32-bit permutation in f    */
  238.  #ifdef DEBUG
  239.  /*deb*/ printf("End init.\n");
  240.  #endif
  241.  }
  242.  
  243.  int bytebit[]               /* bit 0 is left-most in byte    */
  244.      = {    0200,0100,040,020,010,04,02,01 };
  245.  
  246.  int nibblebit[] = { 010,04,02,01 };
  247.  
  248.  sinit()                 /* initialize s1-s8 arrays        */
  249.  {    register int i,j;
  250.  
  251.      for (i=0; i<4; i++)        /* each 12-bit position        */
  252.          for (j=0; j<4096; j++)  /* each possible 12-bit value   */
  253.              s[i][j]=(getcomp(i*2,j>>6)<<4) |
  254.                  (017&getcomp(i*2+1,j&077));
  255.                      /* store 2 compressions per char*/
  256.  }
  257.  
  258.  getcomp(k,v)                /* 1 compression value for sinit*/
  259.  int k,v;
  260.  {    register int i,j;        /* correspond to i and j in FIPS*/
  261.  
  262.      i=((v&040)>>4)|(v&1);        /* first and last bits make row */
  263.      j=(v&037)>>1;            /* middle 4 bits are column    */
  264.      return (int) si[k][(i<<4)+j];   /* result is ith row, jth col   */
  265.  }
  266.  
  267.  kinit(key)                /* initialize key schedule array*/
  268.  char *key;                /* 64 bits (will use only 56)   */
  269.  {    register int i,j,l;
  270.      int m;
  271.  
  272.      for (j=0; j<56; j++)        /* convert pc1 to bits of key   */
  273.      {    l=pc1[j]-1;        /* integer bit location        */
  274.          m = l & 07;        /* find bit            */
  275.          pc1m[j]=(key[l>>3] &    /* find which key byte l is in  */
  276.              bytebit[m])    /* and which bit of that byte   */
  277.              ? 1 : 0;    /* and store 1-bit result    */
  278.      }
  279.      for (i=0; i<16; i++)        /* for each key sched section   */
  280.          for (j=0; j<6; j++)    /* and each byte of the kn    */
  281.              kn[i][j]=0;    /* clear it for accumulation    */
  282.      for (i=0; i<16; i++)        /* key chunk for each iteration */
  283.      {    for (j=0; j<56; j++)    /* rotate pc1 the right amount  */
  284.          pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
  285.              /* rotate left and right halves independently   */
  286.          for (j=0; j<48; j++)    /* select bits individually    */
  287.          if (pcr[pc2[j]-1])    /* check bit that goes to kn[j] */
  288.              {    l= j & 07;
  289.                  kn[i][j>>3] |= bytebit[l];
  290.              }        /* mask it in if it's there    */
  291.      }
  292.  }
  293.  
  294.  p32init()                /* initialize 32-bit permutation*/
  295.  {    register int l, j, k;
  296.      int i,m;
  297.  
  298.      for (i=0; i<4; i++)        /* each input byte position    */
  299.          for (j=0; j<256; j++)    /* all possible input bytes    */
  300.          for (k=0; k<4; k++)    /* each byte of the mask    */
  301.              p32[i][j][k]=0;    /* clear permutation array    */
  302.      for (i=0; i<4; i++)        /* each input byte position    */
  303.          for (j=0; j<256; j++)    /* each possible input byte    */
  304.          for (k=0; k<32; k++)    /* each output bit position    */
  305.          {   l=p32i[k]-1;    /* invert this bit (0-31)    */
  306.              if ((l>>3)!=i)    /* does it come from input posn?*/
  307.              continue;    /* if not, bit k is 0        */
  308.              if (!(j&bytebit[l&07]))
  309.              continue;    /* any such bit in input?    */
  310.              m = k & 07;     /* which bit is it?        */
  311.              p32[i][j][k>>3] |= bytebit[m];
  312.          }
  313.  }
  314.  
  315.  perminit(perm,p)            /* initialize a perm array    */
  316.  char perm[16][16][8];            /* 64-bit, either init or final */
  317.  char p[64];
  318.  {    register int l, j, k;
  319.      int i,m;
  320.  
  321.      for (i=0; i<16; i++)        /* each input nibble position   */
  322.          for (j=0; j<16; j++)    /* all possible input nibbles   */
  323.          for (k=0; k<8; k++)    /* each byte of the mask    */
  324.              perm[i][j][k]=0;/* clear permutation array    */
  325.      for (i=0; i<16; i++)        /* each input nibble position   */
  326.          for (j = 0; j < 16; j++)/* each possible input nibble   */
  327.          for (k = 0; k < 64; k++)/* each output bit position    */
  328.          {   l = p[k] - 1;    /* where does this bit come from*/
  329.              if ((l >> 2) != i)  /* does it come from input posn?*/
  330.              continue;    /* if not, bit k is 0        */
  331.              if (!(j & nibblebit[l & 3]))
  332.              continue;    /* any such bit in input?    */
  333.              m = k & 07;    /* which bit is this in the byte*/
  334.              perm[i][j][k>>3] |= bytebit[m];
  335.          }
  336.  }
  337.  
  338.  iter(num,inblock,outblock)        /* 1 churning operation        */
  339.  int num;                /* i.e. the num-th one        */
  340.  char *inblock, *outblock;        /* 64 bits each            */
  341.  {    char fret[4];            /* return from f(R[i-1],key)    */
  342.      register char *ib, *ob, *fb;
  343.  /*    register int i;    */    /* rwo: unused    */
  344.  
  345.      ob = outblock; ib = &inblock[4];
  346.      f(ib, num, fret);        /* the primary transformation   */
  347.      *ob++ = *ib++;            /* L[i] = R[i-1]        */
  348.      *ob++ = *ib++;
  349.      *ob++ = *ib++;
  350.      *ob++ = *ib++;
  351.      ib = inblock; fb = fret;    /* R[i]=L[i] XOR f(R[i-1],key)  */
  352.      *ob++ = *ib++ ^ *fb++;
  353.      *ob++ = *ib++ ^ *fb++;
  354.      *ob++ = *ib++ ^ *fb++;
  355.      *ob++ = *ib++ ^ *fb++;
  356.  }
  357.  
  358.  f(right,num,fret)            /* critical cryptographic trans */
  359.  char *right, *fret;            /* 32 bits each            */
  360.  int num;                /* index number of this iter    */
  361.  {    register char *kb, *rb, *bb;    /* ptr to key selection &c    */
  362.      char bigright[6];        /* right expanded to 48 bits    */
  363.      char result[6];            /* expand(R) XOR keyselect[num] */
  364.      char preout[4];            /* result of 32-bit permutation */
  365.  
  366.      kb = kn[num];            /* fast version of iteration    */
  367.      bb = bigright;
  368.      rb = result;
  369.      expand(right,bb);        /* expand to 48 bits        */
  370.      *rb++ = *bb++ ^ *kb++;        /* expanded R XOR chunk of key  */
  371.      *rb++ = *bb++ ^ *kb++;
  372.      *rb++ = *bb++ ^ *kb++;
  373.      *rb++ = *bb++ ^ *kb++;
  374.      *rb++ = *bb++ ^ *kb++;
  375.      *rb++ = *bb++ ^ *kb++;
  376.      contract(result,preout);    /* use S fns to get 32 bits    */
  377.      perm32(preout,fret);        /* and do final 32-bit perm    */
  378.  }
  379.  
  380.  perm32(inblock,outblock)        /* 32-bit permutation at end    */
  381.  char *inblock,*outblock;        /* of the f crypto function    */
  382.  {    register int j;
  383.  /*    register int i;    */    /* rwo: unused    */
  384.      register char *ib, *ob;
  385.      register char *q;
  386.  
  387.      ob = outblock;            /* clear output block        */
  388.      *ob++ = 0; *ob++ = 0; *ob++ = 0; *ob++ = 0;
  389.      ib=inblock;            /* ptr to 1st byte of input    */
  390.      for (j=0; j<4; j++, ib++)    /* for each input byte        */
  391.      {    q = p32[j][*ib & 0377];
  392.          ob = outblock;        /* and each output byte        */
  393.          *ob++ |= *q++;        /* OR the 16 masks together    */
  394.          *ob++ |= *q++;
  395.          *ob++ |= *q++;
  396.          *ob++ |= *q++;
  397.      }
  398.  }
  399.  
  400.  expand(right,bigright)            /* 32 to 48 bits with E oper    */
  401.  char *right,*bigright;            /* right is 32, bigright 48    */
  402.  {
  403.      register char *bb, *r, r0, r1, r2, r3;
  404.  
  405.      bb = bigright;
  406.      r = right; r0 = *r++; r1 = *r++; r2 = *r++; r3 = *r++;
  407.      *bb++ = ((r3 & 0001) << 7) |    /* 32                */
  408.          ((r0 & 0370) >> 1) |    /* 1 2 3 4 5            */
  409.          ((r0 & 0030) >> 3);    /* 4 5                */
  410.      *bb++ = ((r0 & 0007) << 5) |    /* 6 7 8            */
  411.          ((r1 & 0200) >> 3) |    /* 9                */
  412.          ((r0 & 0001) << 3) |    /* 8                */
  413.          ((r1 & 0340) >> 5);    /* 9 10 11            */
  414.      *bb++ = ((r1 & 0030) << 3) |    /* 12 13            */
  415.          ((r1 & 0037) << 1) |    /* 12 13 14 15 16        */
  416.          ((r2 & 0200) >> 7);    /* 17                */
  417.      *bb++ = ((r1 & 0001) << 7) |    /* 16                */
  418.          ((r2 & 0370) >> 1) |    /* 17 18 19 20 21        */
  419.          ((r2 & 0030) >> 3);    /* 20 21            */
  420.      *bb++ = ((r2 & 0007) << 5) |    /* 22 23 24            */
  421.          ((r3 & 0200) >> 3) |    /* 25                */
  422.          ((r2 & 0001) << 3) |    /* 24                */
  423.          ((r3 & 0340) >> 5);    /* 25 26 27            */
  424.      *bb++ = ((r3 & 0030) << 3) |    /* 28 29            */
  425.          ((r3 & 0037) << 1) |    /* 28 29 30 31 32        */
  426.          ((r0 & 0200) >> 7);    /* 1                */
  427.  }
  428.  
  429.  contract(in48,out32)            /* contract f from 48 to 32 bits*/
  430.  char *in48,*out32;            /* using 12-bit pieces into bytes */
  431.  {    register char *c;
  432.      register char *i;
  433.      register int i0, i1, i2, i3, i4, i5;
  434.  
  435.      i = in48;
  436.      i0 = *i++; i1 = *i++; i2 = *i++; i3 = *i++; i4 = *i++; i5 = *i++;
  437.      c = out32;            /* do output a byte at a time   */
  438.      *c++ = s[0][07777 & ((i0 << 4) | ((i1 >> 4) & 017  ))];
  439.      *c++ = s[1][07777 & ((i1 << 8) | ( i2    & 0377 ))];
  440.      *c++ = s[2][07777 & ((i3 << 4) | ((i4 >> 4) & 017  ))];
  441.      *c++ = s[3][07777 & ((i4 << 8) | ( i5    & 0377 ))];
  442.  }
  443.  
  444.  /* End of DES algorithm (except for calling desinit below)    */
  445.  
  446.  char *inname, *outname;
  447.  FILE *infile, *outfile;
  448.  
  449.  int encrypting;
  450.  char buf[512];
  451.  char keyx[9], keyy[9];
  452.  
  453.  char *malloc(), *strcpy(), *strcat();
  454.  
  455.  main(argc, argv)
  456.  int argc; char *argv[];
  457.  {    register char *u;
  458.      char *filename;
  459.  
  460.      if (argc < 2)            /* filenames given? */
  461.      {  fprintf(stderr, "Usage: des file ...\n");
  462.         exit(1);     
  463.      }
  464.  
  465.      for (++argv; --argc; ++argv)
  466.      {    inname = *argv;
  467.          outname = filename = malloc((unsigned) strlen(inname) + 3);
  468.          strcpy(filename, inname);
  469.          u = &filename[strlen(filename) - 2]; /* check last 2 chars */
  470.  
  471.          encrypting = (strcmp(".n", u) != 0);
  472.          if (!encrypting) *u = 0; /* strip .n from output filename */
  473.          else strcat(filename, ".n");  /* or add .n to output file */
  474.  
  475.          if ((infile = fopen(inname, "rb")) == NULL)
  476.          {    fprintf(stderr,"Can't read %s.\n", inname);
  477.              exit(1);
  478.          }
  479.          if ((outfile = fopen(outname, "rb")) != NULL)
  480.          {    fprintf(stderr, "%s would be overwritten.\n",outname);
  481.              exit(1);
  482.          }
  483.          if ((outfile = fopen(outname, "wb")) == NULL)
  484.          {    fprintf(stderr,"Can't write %s.\n", outname);
  485.              exit(1);
  486.          }
  487.  
  488.          key_get("Type password for ");
  489.          for (;;)
  490.          {    strcpy(keyx, keyy);
  491.              key_get("Verify password for ");
  492.              if (strcmp(keyx, keyy) == 0) break;
  493.          }
  494.          desinit(keyx);      /* set up tables for DES    */
  495.  
  496.          if (pfile() == 0) unlink(inname);
  497.          else    fprintf(stderr,
  498.                 "%s: I/O Error -- File unchanged\n", inname);
  499.  
  500.          fclose(outfile);
  501.          fclose(infile);
  502.      }
  503.      exit(0);
  504.  }
  505.  
  506.  key_get(mes)            /* get file key */
  507.  char *mes;
  508.  {    register int i, j;
  509.      char linebuf[256];
  510.      int count;
  511.  
  512.      for (i=0; i<14; i++) keyy[i]=0;
  513.  
  514.      printf("%s%s: ", mes, inname);
  515.      fflush(stdout);
  516.  
  517.      count = read(0, linebuf, 256);  /* read input line */
  518.      printf("\n");
  519.  
  520.      linebuf[count] = 0;  /* null terminate */
  521.      if (linebuf[count-1] == '\n')  /* ignore any terminating newline */
  522.      {  linebuf[count-1] = 0;
  523.         count--;     
  524.      }
  525.      if (count > 8) count = 8;    /* only use 8 chars */
  526.      for (i = j = 0; count--;)
  527.         keyy[i++] = linebuf[j++];
  528.  }
  529.  
  530.  pfile()                 /* process the file        */
  531.  {    register int m, nsave;
  532.      register char *b;
  533.      int j;
  534.  
  535.      while (m = fread(buf, 1, 512, infile))
  536.      {
  537.          if ((nsave = m) < 0)    /* read error            */
  538.          return(-1);
  539.          for (b=buf; m>0;    /* encrypt/decrypt 1 buffer-full*/
  540.          m -= 8, b += 8)        /* 8-byte blocks        */
  541.          {   if (encrypting)
  542.          {   if (m<8)        /* don't have a full 64 bits    */
  543.              {   for (j=0; j<8-m; j++)
  544.                  b[m+j]=garbage(); /* fill block with trash  */
  545.              nsave += 8-m;   /* complete the block        */
  546.              }
  547.              else j=0;    /* number of nulls in last block*/
  548.              endes(b,b);    /* don't need diff input, output*/
  549.          }
  550.          else            /* decrypting            */
  551.          {   if (m < 8) deout(b, 1); /* last byte in file: count */
  552.              else
  553.              {   dedes(b, b); /* decrypt and output block    */
  554.              deout(b, 0);
  555.              }
  556.          }
  557.          }
  558.          if (encrypting) if (fwrite(buf, 1, nsave, outfile) != nsave)
  559.              return(-1);
  560.      }
  561.      /* have now encrypted/decrypted the whole file;
  562.       * need to append the byte count for the last block if encrypting.
  563.       */
  564.      if (encrypting) fputc(8 - j, outfile);  /* how many good bytes? */
  565.      return(0);
  566.  }
  567.  
  568.  int outcount = 0;            /* see when caught up with delay*/
  569.  
  570.  deout(block,flag)            /* 1-block delay on output    */
  571.  char *block,flag;            /* 64-bit block, last block flag*/
  572.  {    static char last[8];        /* previous input block        */
  573.      register int i;
  574.  /*    register char *c,*j;    */    /* rwo: unused    */
  575.  
  576.      if (flag)            /* output the last few bytes    */
  577.      {
  578.          fwrite(last, 1, block[0] & 0377, outfile);
  579.          return;
  580.      }
  581.      if (outcount++)            /* seen any blocks before?    */
  582.          fwrite(last, 1, 8, outfile);
  583.      for (i = 0; i < 8; i++) last[i] = block[i]; /* copy the block   */
  584.  }
  585.  
  586.  garbage()                /* generate garbage for filling */
  587.  /* This garbage should be as random as possible.  We're using subsequent calls
  588.   * on the timer, but ideally each byte should be uncorrelated.  Preferable
  589.   * would be to call the timer once and use it to initialize a dumb random
  590.   * number generator.
  591.   */
  592.  {
  593.      long time();
  594.     static inited=0;
  595.  
  596.     if (!inited)
  597.     {
  598.         srand(time((long *)0));
  599.         inited++;
  600.     }
  601.      return (rand());
  602.  }
  603.  /************ end scrydes ************/
  604.